home *** CD-ROM | disk | FTP | other *** search
- Path: news.th-darmstadt.de!news
- From: Enno Sandner <enno@intellektik.informatik.th-darmstadt.de>
- Newsgroups: comp.lang.c++
- Subject: Re: Why use private class members instead of protected?
- Date: Fri, 12 Jan 1996 09:32:44 +0100
- Organization: Fachbereich Informatik, TH Darmstadt
- Message-ID: <30F61CAC.2781E494@intellektik.informatik.th-darmstadt.de>
- References: <30F4AB49.6ABB@sierra.net> <30F50874.15FB7483@intellektik.informatik.th-darmstadt.de> <4d3q07$n8o@geraldo.cc.utexas.edu>
- NNTP-Posting-Host: kitz.intellektik.informatik.th-darmstadt.de
- Mime-Version: 1.0
- Content-Type: text/plain; charset=us-ascii
- Content-Transfer-Encoding: 7bit
- X-Mailer: Mozilla 2.0b4 (X11; I; SunOS 4.1.3 sun4m)
-
- Richard Kilgore wrote:
- >
- > Enno Sandner <enno@intellektik.informatik.th-darmstadt.de> wrote:
- > >TGColwell wrote:
- > >>
- > >> I'm relatively new to c++. I have one quick question: If child
- > >> classes can only access protected members of the parent class,
- > >> why make any members of any class private? Wouldn't it be
- > >> better to make members of the parent class protected so that the
- > >> class is alway "inheritance ready"?
- > >>
- > >
- > >No,
- > >it's quite often a better approach to make these data-members private and
- > >provide the suitable accessor functions. In this way you can change the
- > >representation of the data-members without the problem that modifications
- > >will 'propagate' downwards the class-hierachie.
- > >
- > > Enno
- >
- > I'd like to add my 2 cents worth here. I have on occasion seen the approach
- > of making a data member private, and then providing an accessor/mutator
- > combination method like the following:
- >
- > DataType& MyClass::data() { return _data; }
- >
- > The idea is to provide one function that the user can call to get the data's
- > value OR to change it.
- >
- > This makes no sense to me. You have just set yourself up for a pain in the
- > ass if you ever want to change the internal representation of the data.
- > For example, suppose you store a fraction as two integers and provide
- > accessor/mutators like the line above for each of the numerator and
- > denominator values. Then later you want to represent it as a float and
- > calculate such values on the fly. Don't know if this is a good exmaple
- > of a reasonable thing to do, but you get the picture. Now you're stuck with
- > an interface that promises you can return a REFERENCE to an integer value.
- > But how do you return a reference to something that doesn't exist in memory?
- > One idea is to keep a temporary storage location around for returning such
- > values: a serious kludge in which the user better not hold onto his own
- > reference to your return value, because it might change soon. Another
- > approach entails allocating memory for the return type and expecting the user
- > to free it: Yuck! Inneficient and dangerous. In either case, a user's
- > attempt to use this returned value as an Lvalue will have no effect on the
- > class's data.
- >
- > I realize you might want to return a reference for efficiency's sake, if the
- > data type being returned is large, but there is no reason not to return a
- > CONST reference for this purpose. Then if you ever change the internal
- > implementation of the class, you could use the temporary storage location
- > for return values and not have to worry about cooky side effects.
- >
-
- You're right. If you return a reference to a private data-member changing the
- representation becomes complicated, if not impossible.
- However an accessor/mutator pair like
-
- void MyClass :: set_data(const DataType&) { ... }
- DataType MyClass :: get_data() const { return _data; }
-
- completely avoids this sort of problems. If the 'DataType' uses some technique
- to speed up copying (for example ref-counting) the overhead is minimal.
-
- Enno
-